﻿using System;
using MediatR;
using Casamiel.Domain.Response;
using System.Net.Http;
using Casamiel.Common;
using Casamiel.Domain;
using Microsoft.Extensions.Options;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Linq;
using System.Data;
using Newtonsoft.Json.Linq;
using Casamiel.Common.Extensions;
using Newtonsoft.Json;
using Casamiel.Domain.Response.IC;
using System.Globalization;

namespace Casamiel.Application.Commands
{
	/// <summary>
	/// 
	/// </summary>
	public sealed class GetMyUsableCouponsCommandHandler : BaseCommandHandler, IRequestHandler<GetMyUsableCouponsCommand, BaseResult<List<MemberCouponReponse>>>
	{
		private readonly IMemberCouponGiveRepository _memberCouponGiveRepository;
		private readonly IMemberCouponRepository _memberCouponRepository;
		private readonly IMemberRepository _memberRepository;
		private readonly ICasaMielSession _session;
		private readonly IMbrStoreRepository _mbrStoreRepository;

		/// <summary>
		/// 
		/// </summary>
		/// <param name="casaMielSession"></param>
		/// <param name="memberCouponGiveRepository"></param>
		/// <param name="memberCouponRepositor"></param>
		/// <param name="netICService"></param>
		/// <param name="httpClientFactory"></param>
		/// <param name="settings"></param>
		/// <param name="memberRepository"></param>
		public GetMyUsableCouponsCommandHandler(ICasaMielSession casaMielSession, IMemberCouponGiveRepository memberCouponGiveRepository, IMemberCouponRepository memberCouponRepositor, INetICService netICService,
			IHttpClientFactory httpClientFactory, IMbrStoreRepository mbrStoreRepository, IOptionsSnapshot<CasamielSettings> settings, IMemberRepository memberRepository) : base(netICService, httpClientFactory, settings)

		{
			_session = casaMielSession;
			_memberCouponGiveRepository = memberCouponGiveRepository;
			_memberCouponRepository = memberCouponRepositor;
			_memberRepository = memberRepository;
			_mbrStoreRepository = mbrStoreRepository;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="request"></param>
		/// <param name="cancellationToken"></param>
		/// <returns></returns>
		public async Task<BaseResult<List<MemberCouponReponse>>> Handle(GetMyUsableCouponsCommand request, CancellationToken cancellationToken)
		{
			if (request is null) {
				throw new ArgumentNullException(nameof(request));
			}

			var member = await _memberRepository.FindAsync<ICasaMielSession>(request.Mobile).ConfigureAwait(false);
			if (member == null) {
				return new BaseResult<List<MemberCouponReponse>>(new List<MemberCouponReponse>(), 999, "会员不存在");
			}

			var list = await _memberCouponGiveRepository.GetListAsync<ICasaMielSession>(member.ID, 0, false, DateTime.Now.AddHours(-48)).ConfigureAwait(false);
			if (list.Any()) {
				var listCount = list.Count;
				for (int i = 0; i < listCount; i++) {
					var entity = await _memberCouponRepository.GetKeyAsync<ICasaMielSession>(list[i].MCID).ConfigureAwait(false);
					if (entity == null) continue;

					list[i].Status = -1;
					list[i].LastTime = DateTime.Now;
					await _memberCouponGiveRepository.UpdateAsync<ICasaMielSession>(list[i]).ConfigureAwait(false);

					var items = await _memberCouponGiveRepository.GetListAsync<ICasaMielSession>(member.ID, list[i].MCID, 0, true, DateTime.Now.AddHours(-48)).ConfigureAwait(false);
					if (!items.Any() && entity.GiveStatus == -1) {
						using (var uow = _session.UnitOfWork(IsolationLevel.Serializable)) {
							await _memberCouponRepository.UpdateCouponGiveStatusAsnync(entity, 0, uow).ConfigureAwait(false);
						}
					}
				}
			}
			//var Couponlist = await _memberCouponRepository.GetListAsnyc<ICasaMielSession>(member.ID, 0, DateTime.Now.AddDays(-7)).ConfigureAwait(false);
			//if (Couponlist.Any()) {
			//	var count = list.Count();
			//	for (int i = 0; i < count; i++) {
			//		var coupon = Couponlist[i];
			//		if (coupon.State != 0) {
			//			continue;
			//		}
			//		var irsp = await NetICService.Tmticketquery(new Domain.Request.IC.TmticketqueryReq { ticketcode = Couponlist[i].Ticketcode }).ConfigureAwait(false);
			//		if (irsp.code == 0) {
			//			var j = JObject.Parse(irsp.content);
			//			var state = j["state"].ToInt16(0);

			//			var Startdate = DateTime.Parse(j["startdate"].ToString(), CultureInfo.InvariantCulture);
			//			var Enddate = DateTime.Parse(j["enddate"].ToString(), CultureInfo.InvariantCulture);
			//			if (state != Couponlist[i].State || !coupon.UsedDate.HasValue) {
			//				coupon.State = state;

			//				coupon.Productname = j["productname"].ToString();
			//				coupon.Productid = j["productid"].ToInt64(0);
			//				coupon.Startdate = Startdate;
			//				coupon.Enddate = Enddate;
			//				if (coupon.State == 0) {
			//					coupon.UsedDate = DateTime.Parse(j["usedddate"].ToString(), CultureInfo.InvariantCulture);
			//				}
			//				await _memberCouponRepository.UpdateAsync<ICasaMielSession>(coupon).ConfigureAwait(false);
			//			}
			//		}
			//	}
			//}

			var rsp = await _memberCouponRepository.GetListAsnyc<ICasaMielSession>(member.ID, request.State, 1, 999).ConfigureAwait(false);
			if (rsp.Content.Any()) {
				var count = rsp.Content.Count();
				for (int i = 0; i < count; i++) {
					var coupon = rsp.Content[i];
					var irsp = await NetICService.Tmticketquery(new Domain.Request.IC.TmticketqueryReq { ticketcode = rsp.Content[i].Ticketcode }).ConfigureAwait(false);
					if (irsp.code == 0) {
						var j = JObject.Parse(irsp.content);
						var state = j["state"].ToInt16(0);
						var Startdate = DateTime.Parse(j["startdate"].ToString(), CultureInfo.InvariantCulture);
						var Enddate = DateTime.Parse(j["enddate"].ToString(), CultureInfo.InvariantCulture);

						if (state != rsp.Content[i].State|| Enddate!=coupon.Enddate) {
							coupon.State = state;
							rsp.Content[i].State = state;
							coupon.Startdate = Startdate;
							coupon.Enddate = Enddate;
							await _memberCouponRepository.UpdateAsync<ICasaMielSession>(coupon).ConfigureAwait(false);
						}


						//var irsp = await NetICService.Tmticketquery(new Domain.Request.IC.TmticketqueryReq { ticketcode = rsp.Content[i].Ticketcode }).ConfigureAwait(false);
						//if (irsp.code == 0) {
						//	var j = JObject.Parse(irsp.content);
						//	var state = j["state"].ToInt16(0);
						//	if (state != rsp.Content[i].State) {
						//		coupon.State = state;
						//		rsp.Content[i].State = state;
						//		coupon.Productname = j["productname"].ToString();
						//		coupon.Productid = j["productid"].ToInt64(0);
						//		coupon.Startdate = DateTime.Parse(j["startdate"].ToString(), CultureInfo.InvariantCulture);
						//		coupon.Enddate = DateTime.Parse(j["enddate"].ToString(), CultureInfo.InvariantCulture);
						//		await _memberCouponRepository.UpdateAsync<ICasaMielSession>(coupon).ConfigureAwait(false);
						//	}
						//}
					}
				}
				var dd = from x in rsp.Content.Where(c => c.State == request.State)
						 select (new MemberCouponReponse {
							 MID = x.MID,
							 GiveStatus = x.GiveStatus,
							 MCID = x.MCID,
							 Productname = x.Productname,
							 Enddate = x.Enddate,
							 Price = x.Price,
							 Startdate = x.Startdate,
							 State = x.State,
							 Productid = x.Productid


						 });


				var OrderAmount = request.GoodsList.Sum(c => c.GoodsQuantity * c.Price);
				var storeInfo = await _mbrStoreRepository.GetByStoreIdAsync<ICasaMielSession>(request.StoreId).ConfigureAwait(false);
				if (storeInfo == null) {
					return new BaseResult<List<MemberCouponReponse>>(new List<MemberCouponReponse>(), 0, "");
				}
				List<long> ids = new List<long>();
				foreach (var item in dd) {
					if (ids.Contains(item.Productid)) {
						continue;
					}
					ids.Add(item.Productid);
				}
				if (ids.Any()) {
					var ticketLimit = await NetICService.TicketLimit(storeInfo.RelationId, ids, 0, true).ConfigureAwait(false);
					var rule = JsonConvert.DeserializeObject<TicketsRules>(ticketLimit.content);


					Console.WriteLine(JsonConvert.SerializeObject(ticketLimit));
					var count1 = dd.Count();
					var ticketlist = dd.ToList();
					if (count1 > 0) {

						Parallel.For(0, count1, (i) => {
							var list216 = rule.Tickets.Where(c => c.Limittype == 216 && c.Productid == ticketlist[i].Productid);
							if (list216.Any()) {
								bool s = false;
								var list216msg = "";
								foreach (var item in list216) {
									var ss = request.GoodsList.Count(c => c.GoodsRelationId == int.Parse(item.Limitvalue, System.Globalization.CultureInfo.CurrentCulture));
									if (ss > 0) {
										s = true;
									} else {
										list216msg += $"{item.Productname}{item.Limitdesc}";
									}
								}
								if (!s) {
									ticketlist[i].State = 0;
								}
							}

							var list215 = rule.Tickets.Where(c => c.Limittype == 215 && c.Productid == ticketlist[i].Productid);
							if (list215.Any()) {
								var list215sucess = true;
								var amsg = "";
								foreach (var item in list215) {
									if (!request.GoodsList.Any(c => c.GoodsRelationId == int.Parse(item.Limitvalue, System.Globalization.CultureInfo.CurrentCulture))) {
										amsg += $"{item.Productname}{item.Limitdesc}";
										list215sucess = false;
									}
								}
								if (!list215sucess) {
									ticketlist[i].State = 0;
								}

							}
							var abc = rule.Tickets.Where(c => c.Productid == ticketlist[i].Productid).ToList();
							foreach (var item in abc) {
								if (item.Limittype == 51) {
									var tamount = OrderAmount;

									if (DateTime.Now.Month >= 7 && request.IsTakeOut) {
										if (OrderAmount >= 40) {
											tamount -= 5;
										}
									}
									if (tamount < item.Limitvalue.ToDecimal(0)) {
										ticketlist[i].State = 0;
									}
								}
								if (item.Limittype == 21) {
									var aa = request.GoodsList.Count(c => c.GoodsRelationId == int.Parse(item.Limitvalue, System.Globalization.CultureInfo.CurrentCulture));
									if (aa < 1) {
										ticketlist[i].State = 0;
									}
								}
								if (item.Limittype == 22) {
									var aa = request.GoodsList.Count(c => c.GoodsRelationId == int.Parse(item.Limitvalue, System.Globalization.CultureInfo.CurrentCulture));
									if (aa > 0) {
										ticketlist[i].State = 0;
									}
								}
							}
						});
						var content = ticketlist.OrderByDescending(c => c.State).ToList();
						return new BaseResult<List<MemberCouponReponse>>(content, 0, "");
					}
				}
				return new BaseResult<List<MemberCouponReponse>>(new List<MemberCouponReponse>(), 0, "");

			}

			return new BaseResult<List<MemberCouponReponse>>(new List<MemberCouponReponse>(), 0, "");
		}
	}
}
